Skip to content

[DirectX] ForwardHandle needs to check if globals were stored on allocas #151751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 7, 2025

Conversation

farzonl
Copy link
Member

@farzonl farzonl commented Aug 1, 2025

fixes #140819

SROA pass is making it so that some globals get loaded into stack allocations. This means we find an alloca where we use to expect a load and now need to walk an alloca -> store -> maybe load chain before we find the global. Doing so fixes All but two instances of #137715 And fixes every instance of `Load of "8.sroa.0" is not a global resource handle we are currently seeing in the DML shaders.

fixes llvm#140819

SROA pass is making it so that some globals get loaded into stack
allocations. This means we find an alloca where we use to expect a load
and now need to walk an alloca -> store -> maybe load chain before
we find the global. Doing so fixes All but two instances of llvm#137715
And fixes every instance of `Load of "8.sroa.0" is not a global resource handle
we are currently seeing in the DML shaders.
@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2025

@llvm/pr-subscribers-backend-directx

Author: Farzon Lotfi (farzonl)

Changes

fixes #140819

SROA pass is making it so that some globals get loaded into stack allocations. This means we find an alloca where we use to expect a load and now need to walk an alloca -> store -> maybe load chain before we find the global. Doing so fixes All but two instances of #137715 And fixes every instance of `Load of "8.sroa.0" is not a global resource handle we are currently seeing in the DML shaders.


Full diff: https://github.com/llvm/llvm-project/pull/151751.diff

2 Files Affected:

  • (modified) llvm/lib/Target/DirectX/DXILForwardHandleAccesses.cpp (+33-2)
  • (added) llvm/test/CodeGen/DirectX/issue-140819_allow_forward_handle_on_alloca.ll (+39)
diff --git a/llvm/lib/Target/DirectX/DXILForwardHandleAccesses.cpp b/llvm/lib/Target/DirectX/DXILForwardHandleAccesses.cpp
index 73abfe7c48584..747472b1a4bc1 100644
--- a/llvm/lib/Target/DirectX/DXILForwardHandleAccesses.cpp
+++ b/llvm/lib/Target/DirectX/DXILForwardHandleAccesses.cpp
@@ -87,17 +87,48 @@ static bool forwardHandleAccesses(Function &F, DominatorTree &DT) {
 
   for (LoadInst *LI : LoadsToProcess) {
     Value *V = LI->getPointerOperand();
-    auto *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand());
+    auto *GV = dyn_cast<GlobalVariable>(V);
 
     // If we didn't find the global, we may need to walk through a level of
     // indirection. This generally happens at -O0.
-    if (!GV)
+    if (!GV) {
       if (auto *NestedLI = dyn_cast<LoadInst>(V)) {
         BasicBlock::iterator BBI(NestedLI);
         Value *Loaded = FindAvailableLoadedValue(
             NestedLI, NestedLI->getParent(), BBI, 0, nullptr, nullptr);
         GV = dyn_cast_or_null<GlobalVariable>(Loaded);
+      } else if (auto *NestedAlloca = dyn_cast<AllocaInst>(V)) {
+        for (auto &Use : NestedAlloca->uses()) {
+          auto *Store = dyn_cast<StoreInst>(Use.getUser());
+          if (!Store)
+            continue;
+
+          Value *StoredVal = Store->getValueOperand();
+          if (!StoredVal)
+            continue;
+
+          // Try direct global match
+          GV = dyn_cast<GlobalVariable>(StoredVal);
+          if (GV)
+            break;
+
+          // If it's a load, check its source
+          if (auto *Load = dyn_cast<LoadInst>(StoredVal)) {
+            GV = dyn_cast<GlobalVariable>(Load->getPointerOperand());
+            if (GV)
+              break;
+
+            // Try to find available loaded value
+            BasicBlock::iterator BBI(Load);
+            Value *Loaded = FindAvailableLoadedValue(Load, Load->getParent(),
+                                                     BBI, 0, nullptr, nullptr);
+            GV = dyn_cast<GlobalVariable>(Loaded);
+            if (GV)
+              break;
+          }
+        }
       }
+    }
 
     auto It = HandleMap.find(GV);
     if (It == HandleMap.end()) {
diff --git a/llvm/test/CodeGen/DirectX/issue-140819_allow_forward_handle_on_alloca.ll b/llvm/test/CodeGen/DirectX/issue-140819_allow_forward_handle_on_alloca.ll
new file mode 100644
index 0000000000000..0c1ccb50caee7
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/issue-140819_allow_forward_handle_on_alloca.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -dxil-forward-handle-accesses  %s | FileCheck %s
+
+%"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", i32, 1, 0) }
+@_ZL4dest = internal unnamed_addr global %"class.hlsl::RWStructuredBuffer" poison, align 4
+@.str = private unnamed_addr constant [5 x i8] c"dest\00", align 1
+
+
+; NOTE: intent of this test is to confirm load target("dx.RawBuffer", i32, 1, 0)
+;       is replaced with call @llvm.dx.resource.getpointer
+define void @CSMain() local_unnamed_addr {
+; CHECK-LABEL: define void @CSMain() local_unnamed_addr {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[AGG_TMP_I1_SROA_0:%.*]] = alloca target("dx.RawBuffer", i32, 1, 0), align 8
+; CHECK-NEXT:    [[TMP0:%.*]] = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false, ptr nonnull @.str)
+; CHECK-NEXT:    store target("dx.RawBuffer", i32, 1, 0) [[TMP0]], ptr @_ZL4dest, align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.dx.thread.id(i32 0)
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr @_ZL4dest, align 4
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[AGG_TMP_I1_SROA_0]])
+; CHECK-NEXT:    store i32 [[TMP2]], ptr [[AGG_TMP_I1_SROA_0]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0) [[TMP0]], i32 [[TMP1]])
+; CHECK-NEXT:    store i32 0, ptr [[TMP3]], align 4
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[AGG_TMP_I1_SROA_0]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  %agg.tmp.i1.sroa.0 = alloca target("dx.RawBuffer", i32, 1, 0), align 8
+  %0 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false, ptr nonnull @.str)
+  store target("dx.RawBuffer", i32, 1, 0) %0, ptr @_ZL4dest, align 4
+  %1 = tail call i32 @llvm.dx.thread.id(i32 0)
+  %2 = load i32, ptr @_ZL4dest, align 4
+  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %agg.tmp.i1.sroa.0)
+  store i32 %2, ptr %agg.tmp.i1.sroa.0, align 8
+  %agg.tmp.i1.sroa.0.0.agg.tmp.i1.sroa.0.0.agg.tmp.i1.sroa.0.0.agg.tmp.i1.sroa.0.0. = load target("dx.RawBuffer", i32, 1, 0), ptr %agg.tmp.i1.sroa.0, align 8
+  %3 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0) %agg.tmp.i1.sroa.0.0.agg.tmp.i1.sroa.0.0.agg.tmp.i1.sroa.0.0.agg.tmp.i1.sroa.0.0., i32 %1)
+  store i32 0, ptr %3, align 4
+  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %agg.tmp.i1.sroa.0)
+  ret void
+}

@alsepkow
Copy link
Contributor

alsepkow commented Aug 1, 2025

LGTM.

@farzonl
Copy link
Member Author

farzonl commented Aug 7, 2025

Failure is in compilerRT not any of our code, going to bypass merge rule.

@farzonl farzonl merged commit 04672e2 into llvm:main Aug 7, 2025
9 of 10 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 7, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-aarch64-darwin running on doug-worker-5 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/24994

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli -jit-kind=orc-lazy -compile-threads=2 -thread-entry hello /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll | /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll # RUN: at line 1
+ /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli -jit-kind=orc-lazy -compile-threads=2 -thread-entry hello /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll
+ /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
 #0 0x00000001052c3df0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100f0bdf0)
 #1 0x00000001052c1ba0 llvm::sys::RunSignalHandlers() (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100f09ba0)
 #2 0x00000001052c48f0 SignalHandler(int, __siginfo*, void*) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100f0c8f0)
 #3 0x000000019f823584 (/usr/lib/system/libsystem_platform.dylib+0x18047b584)
 #4 0x000000019f7f221c (/usr/lib/system/libsystem_pthread.dylib+0x18044a21c)
 #5 0x000000019f718ad0 (/usr/lib/libc++.1.dylib+0x180370ad0)
 #6 0x0000000104e4b824 void llvm::detail::UniqueFunctionBase<void, llvm::Expected<llvm::DenseMap<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef, llvm::DenseMapInfo<llvm::orc::SymbolStringPtr, void>, llvm::detail::DenseMapPair<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef>>>>::CallImpl<llvm::orc::Platform::lookupInitSymbols(llvm::orc::ExecutionSession&, llvm::DenseMap<llvm::orc::JITDylib*, llvm::orc::SymbolLookupSet, llvm::DenseMapInfo<llvm::orc::JITDylib*, void>, llvm::detail::DenseMapPair<llvm::orc::JITDylib*, llvm::orc::SymbolLookupSet>> const&)::$_45>(void*, llvm::Expected<llvm::DenseMap<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef, llvm::DenseMapInfo<llvm::orc::SymbolStringPtr, void>, llvm::detail::DenseMapPair<llvm::orc::SymbolStringPtr, llvm::orc::ExecutorSymbolDef>>>&) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100a93824)
 #7 0x0000000104e47458 llvm::orc::AsynchronousSymbolQuery::handleComplete(llvm::orc::ExecutionSession&)::RunQueryCompleteTask::run() (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100a8f458)
 #8 0x0000000104f0f354 void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, llvm::orc::DynamicThreadPoolTaskDispatcher::dispatch(std::__1::unique_ptr<llvm::orc::Task, std::__1::default_delete<llvm::orc::Task>>)::$_0>>(void*) (/Users/buildbot/buildbot-root/aarch64-darwin/build/bin/lli+0x100b57354)
 #9 0x000000019f7f2f94 (/usr/lib/system/libsystem_pthread.dylib+0x18044af94)
#10 0x000000019f7edd34 (/usr/lib/system/libsystem_pthread.dylib+0x180445d34)
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll

--

********************


@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 7, 2025

LLVM Buildbot has detected a new failure on builder lldb-aarch64-windows running on linaro-armv8-windows-msvc-05 while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/141/builds/10645

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: commands/platform/process/launch/TestPlatformProcessLaunch.py (200 of 2293)
UNSUPPORTED: lldb-api :: commands/platform/process/list/TestProcessList.py (201 of 2293)
UNSUPPORTED: lldb-api :: commands/platform/sdk/TestPlatformSDK.py (202 of 2293)
PASS: lldb-api :: commands/plugin/TestPlugin.py (203 of 2293)
UNSUPPORTED: lldb-api :: commands/process/attach-resume/TestAttachResume.py (204 of 2293)
PASS: lldb-api :: commands/process/attach/TestProcessAttach.py (205 of 2293)
UNSUPPORTED: lldb-api :: commands/process/attach/attach_denied/TestAttachDenied.py (206 of 2293)
PASS: lldb-api :: commands/process/continue_to_bkpt/TestContinueToBkpts.py (207 of 2293)
XFAIL: lldb-api :: commands/platform/connect/TestPlatformConnect.py (208 of 2293)
UNSUPPORTED: lldb-api :: commands/process/handle/TestProcessHandle.py (209 of 2293)
FAIL: lldb-api :: commands/process/detach-resumes/TestDetachResumes.py (210 of 2293)
******************** TEST 'lldb-api :: commands/process/detach-resumes/TestDetachResumes.py' FAILED ********************
Script:
--
C:/Users/tcwg/scoop/apps/python/current/python.exe C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/llvm-project/lldb\test\API\dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./lib --env LLVM_INCLUDE_DIR=C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/include --env LLVM_TOOLS_DIR=C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./bin --arch aarch64 --build-dir C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/lldb-test-build.noindex --lldb-module-cache-dir C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/lldb-test-build.noindex/module-cache-lldb\lldb-api --clang-module-cache-dir C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/lldb-test-build.noindex/module-cache-clang\lldb-api --executable C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./bin/lldb.exe --compiler C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./bin/clang.exe --dsymutil C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./bin/dsymutil.exe --make C:/Users/tcwg/scoop/shims/make.exe --llvm-tools-dir C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./bin --lldb-obj-root C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/tools/lldb --lldb-libs-dir C:/Users/tcwg/llvm-worker/lldb-aarch64-windows/build/./lib --cmake-build-type Release --skip-category=watchpoint C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\commands\process\detach-resumes -p TestDetachResumes.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 22.0.0git (https://github.com/llvm/llvm-project.git revision 04672e20d43679db4b13b8f9d19e3a2b748bca4f)
  clang revision 04672e20d43679db4b13b8f9d19e3a2b748bca4f
  llvm revision 04672e20d43679db4b13b8f9d19e3a2b748bca4f
Skipping the following test categories: ['watchpoint', 'libc++', 'libstdcxx', 'dwo', 'dsym', 'gmodules', 'debugserver', 'objc', 'fork', 'pexpect']


--
Command Output (stderr):
--
FAIL: LLDB (C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\bin\clang.exe-aarch64) :: test_detach_resumes (TestDetachResumes.DetachResumesTestCase.test_detach_resumes)

======================================================================

FAIL: test_detach_resumes (TestDetachResumes.DetachResumesTestCase.test_detach_resumes)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\decorators.py", line 151, in wrapper

    return func(*args, **kwargs)

           ^^^^^^^^^^^^^^^^^^^^^

  File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\commands\process\detach-resumes\TestDetachResumes.py", line 62, in test_detach_resumes

    self.runCmd("detach")


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DirectX] Error occurs when using global resource handles in function parameters or when compiling with -O0
5 participants